/**
  ******************************************************************************
  * @file           : vfdbsp.c
  * @brief          : Variable-frequency bsp program
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
#include "bsp.h"
#include "tskcfg.h"
#include "ctrl_common.h"

#define VFD_485_DIR_Pin           GPIO_PIN_13
#define VFD_485_DIR_GPIO_Port     GPIOD
#define VFD_485_DIR(x)            x?(GPIO_BOP(VFD_485_DIR_GPIO_Port) = (uint32_t)VFD_485_DIR_Pin):(GPIO_BC(VFD_485_DIR_GPIO_Port) = (uint32_t)VFD_485_DIR_Pin)

/* USART3 init function */
void VFD_BspInit(void)
{
  rcu_periph_clock_enable(RCU_GPIOE);
  rcu_periph_clock_enable(RCU_GPIOD);
	rcu_periph_clock_enable(RCU_SYSCFG);
	rcu_periph_clock_enable(RCU_UART6);
	
	gpio_mode_set(VFD_485_DIR_GPIO_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, VFD_485_DIR_Pin);
	gpio_output_options_set(VFD_485_DIR_GPIO_Port, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, VFD_485_DIR_Pin);
	
	gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7);
	gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_8);
	
	/* configure USART2 Tx as alternate function push-pull */
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);

	/* configure USART2 Rx as alternate function push-pull */
	gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8);
	gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
	
  /* USART configure */
	usart_deinit(UART6);
	usart_baudrate_set(UART6, 19200u);
	usart_word_length_set(UART6, USART_WL_8BIT);
	usart_parity_config(UART6, USART_PM_NONE);
	usart_stop_bit_set(UART6, USART_STB_1BIT);
	usart_receive_config(UART6, USART_RECEIVE_DISABLE);
	usart_transmit_config(UART6, USART_TRANSMIT_ENABLE);
	usart_halfduplex_disable(UART6);
	usart_synchronous_clock_disable(UART6);
	
	usart_receiver_timeout_disable(UART6);
	
	nvic_irq_disable(UART6_IRQn);
	usart_interrupt_disable(UART6, USART_INT_RBNE);
	usart_interrupt_disable(UART6, USART_INT_RT);
	
	usart_enable(UART6);
}

void Ctr_TCTimerInit(void)
{
	timer_parameter_struct timer_initpara;
	
	rcu_periph_clock_enable(CTR_TC_TIMER_CLOCK);
	rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
	
	timer_deinit(CTR_TC_TIMER);
	timer_struct_para_init(&timer_initpara);
	timer_initpara.prescaler         = 40000u;
  timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
  timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  timer_initpara.period            = 5000u;
  timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  timer_initpara.repetitioncounter = 0U;
	timer_init(CTR_TC_TIMER, &timer_initpara);
	
	timer_interrupt_flag_clear(CTR_TC_TIMER, TIMER_INT_FLAG_UP);
	timer_flag_clear(CTR_TC_TIMER, TIMER_FLAG_UP);
	
	timer_auto_reload_shadow_enable(CTR_TC_TIMER);
	timer_single_pulse_mode_config(CTR_TC_TIMER, TIMER_SP_MODE_REPETITIVE);
	
	timer_interrupt_enable(CTR_TC_TIMER, TIMER_INT_UP);
	
	nvic_irq_enable(CTR_TC_TIMER_IRQn, CTR_TC_TIMER_IRQ_PRIORITY, 0);
	
	timer_enable(CTR_TC_TIMER);
}

void VFD_Rs485Send(const uint8_t *buf, uint32_t len)
{
	uint32_t i;
  
	VFD_485_DIR(1);
	vTaskDelay(1);
	
	for(i=0; i<len; i++)
	{
    USART_DATA(UART6) = (buf[i]& (uint16_t)0x01FFU);
    while(!(USART_STAT0(UART6) & USART_STAT0_TBE));
	}
	
	while (!(USART_STAT0(UART6) & USART_STAT0_TC));
	
	vTaskDelay(1);
	VFD_485_DIR(0);
}

/**
  * @brief This function handles USART3 global interrupt.
  */
void UART6_IRQHandler(void)
{
	if(usart_interrupt_flag_get(UART6, USART_INT_FLAG_RBNE) != RESET)
	{
	}
}

void CTR_TC_TIMER_IRQHandler(void)
{
	if(timer_interrupt_flag_get(CTR_TC_TIMER, TIMER_INT_FLAG_UP) != RESET)
	{
		timer_interrupt_flag_clear(CTR_TC_TIMER, TIMER_INT_FLAG_UP);
		
		CtrFan_TimeCtrlISR();
		CtrShl_TimeCtrlISR();
		CtrNuq_TimeCtrlISR();
		CtrVfd_TimeCtrlISR();
	}
}
